package club.monkeywood.ad.dmp.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;


public class BaiduGeoApi {

    //逆地理编码
    //输入：经纬度
    //输出：商圈信息
    public static String getBusiness(String log, String lat) throws IOException, NoSuchAlgorithmException {

        // -----------------------------------------------------------------------
        // 1）获取百度api调用签码-----------------------------------------------
        // 计算sn跟参数对出现顺序有关，get请求请使用LinkedHashMap保存<key,value>，
        // 该方法根据key的插入顺序排序；post请使用TreeMap保存<key,value>，
        // 该方法会自动将key按照字母a-z顺序排序。
        // 所以get请求可自定义参数顺序（sn参数必须在最后）发送请求，
        // 但是post请求必须按照字母a-z顺序填充body（sn参数必须在最后）。
        // 以get请求为例：http://api.map.baidu.com/reverse_geocoding/v3/?location=30.5455298053976,114.27747648130438&output=json&ak=yourak
        // paramsMap中先放入location，再放output，然后放ak，放入顺序必须跟get请求中对应参数的出现顺序保持一致。
        Map paramsMap = new LinkedHashMap<String, String>();
        paramsMap.put("callback", "renderReverse");
        String latAndLong = lat + "," + log;
        paramsMap.put("location", latAndLong);
        paramsMap.put("output", "json");
        paramsMap.put("extensions_poi", "1");

        Config config = ConfigFactory.load();
        String ak = config.getString("baidu.ak");
        paramsMap.put("ak", ak);

        // 调用下面的toQueryString方法，对LinkedHashMap内所有value作utf8编码，
        // 拼接返回结果callback=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourak
        String paramsStr = toQueryString(paramsMap);
        System.out.println("参数="+paramsStr);

        // 对paramsStr前面拼接上/reverse_geocoding/v3/?，后面直接拼接yoursk得到
        // /reverse_geocoding/v3/?callback=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyoursk
        String sk = config.getString("baidu.sk");
        String wholeStr = new String("/reverse_geocoding/v3/?" + paramsStr + sk);

        // 对上面wholeStr再作utf8编码
        String tempStr = URLEncoder.encode(wholeStr, "UTF-8");

        // 调用下面的MD5方法得到最后的sn签名dc8a72b212a6a223aefe0a17ee086e46
        String sn = MD5(tempStr);
        System.out.println("sn="+sn);

        // 2)向百度开放平台发送get请求，请求商圈信息--------------------------------------------------
        String business = null;
        HttpClient httpClient = new HttpClient();
        //从配置文件中取出百度逆地理编码url
        String url = config.getString("baidu.reverse_geocoding_v3");
        GetMethod getMethod = new GetMethod(url + paramsStr +"&sn="+sn);
        int code = httpClient.executeMethod(getMethod);
        if (code == 200) {
            // 获取本次请求的响应内容:
            //renderReverse&&renderReverse({"status":0,"result":{"location":{"lng":114.2774764813043,"lat":30.54552971153468},"formatted_address":"湖北省武汉市汉阳区鹦鹉小道","business":"鹦鹉/鹦鹉大道,江汉大学,腰路堤","addressComponent":{"country":"中国","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","province":"湖北省","city":"武汉市","city_level":2,"district":"汉阳区","town":"","adcode":"420105","street":"鹦鹉小道","street_number":"","direction":"","distance":""},"pois":[{"addr":"武汉汉阳区鹦鹉街办事处世茂锦绣长江二期","cp":"","direction":"内","distance":"0","name":"世茂锦绣长江2期","poiType":"房地产","point":{"x":114.27836661867033,"y":30.545426632277523},"tag":"房地产;住宅区","tel":"","uid":"4fb8a45a2c5615d4b75f1eef","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"鹦鹉小道17号","cp":" ","direction":"东北","distance":"83","name":"江景园","poiType":"房地产","point":{"x":114.27702814346047,"y":30.545006751698226},"tag":"房地产;住宅区","tel":"","uid":"881a28e7b83af144f942b2d7","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"鹦鹉小道1号","cp":" ","direction":"南","distance":"178","name":"锦绣苑","poiType":"房地产","point":{"x":114.27689339763397,"y":30.546826220962758},"tag":"房地产;住宅区","tel":"","uid":"86828754251cc6a18bdb739b","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区鹦鹉小道29","cp":" ","direction":"北","distance":"192","name":"东星公寓","poiType":"房地产","point":{"x":114.27685746541357,"y":30.54413588242787},"tag":"房地产;住宅区","tel":"","uid":"4630efce6af8a07b5bf6be6a","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区腰路堤30号","cp":" ","direction":"南","distance":"236","name":"睿智幼儿园","poiType":"教育培训","point":{"x":114.27706407568087,"y":30.54733162297987},"tag":"教育培训;幼儿园","tel":"","uid":"3c23b5470bb36606a7c756f6","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区武汉世茂希尔顿酒店5号商寓楼41层","cp":" ","direction":"西","distance":"245","name":"爱弥儿舞蹈艺术","poiType":"教育培训","point":{"x":114.2796242463843,"y":30.545107834227534},"tag":"教育培训;幼儿园","tel":"","uid":"ce2c20de6d424e8cf922138a","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区腰路堤43号","cp":" ","direction":"南","distance":"246","name":"杨泗社区","poiType":"房地产","point":{"x":114.27701916040538,"y":30.547401601511259},"tag":"房地产;住宅区","tel":"","uid":"8e2a741ae09352728bb988d4","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"自力新村42附1","cp":" ","direction":"东","distance":"305","name":"鹦鹉街社区卫生中心","poiType":"医疗","point":{"x":114.27473746441003,"y":30.545426632277523},"tag":"医疗;诊所","tel":"","uid":"00a528f9fa63fb98f822130b","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区阳新路","cp":" ","direction":"西北","distance":"322","name":"世茂锦绣长江52","poiType":"购物","point":{"x":114.2799476363679,"y":30.544221414580585},"tag":"购物;购物中心","tel":"","uid":"abb960cc825fa4944d776ec7","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区鹦鹉洲长江大桥下","cp":" ","direction":"西北","distance":"671","name":"鹦鹉洲汉阳桥梁主题公园","poiType":"旅游景点","point":{"x":114.2797949244312,"y":30.540706757987107},"tag":"旅游景点;公园","tel":"","uid":"5111b3c127ec596788db730d","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}}],"roads":[],"poiRegions":[{"direction_desc":"内","name":"世茂锦绣长江2期","tag":"房地产;住宅区","uid":"4fb8a45a2c5615d4b75f1eef","distance":"0"}],"sematic_description":"世茂锦绣长江2期内","cityCode":218}})
            String responseBody = getMethod.getResponseBodyAsString();
            System.out.println("响应内容:" + responseBody);

            getMethod.releaseConnection();

            if(responseBody.startsWith("renderReverse&&renderReverse(")) {
                //去掉无用的头信息
                String replaced = responseBody.replace("renderReverse&&renderReverse(", "");
                replaced = replaced.substring(0, replaced.lastIndexOf(")"));
                // System.out.println("replaced = " + replaced);

                // 解析json字符串 --- fastjson
                // {"status":0,"result":{"location":{"lng":114.2774764813043,"lat":30.54552971153468},"formatted_address":"湖北省武汉市汉阳区鹦鹉小道","business":"鹦鹉/鹦鹉大道,江汉大学,腰路堤","addressComponent":{"country":"中国","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","province":"湖北省","city":"武汉市","city_level":2,"district":"汉阳区","town":"","adcode":"420105","street":"鹦鹉小道","street_number":"","direction":"","distance":""},"pois":[{"addr":"武汉汉阳区鹦鹉街办事处世茂锦绣长江二期","cp":"","direction":"内","distance":"0","name":"世茂锦绣长江2期","poiType":"房地产","point":{"x":114.27836661867033,"y":30.545426632277523},"tag":"房地产;住宅区","tel":"","uid":"4fb8a45a2c5615d4b75f1eef","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"鹦鹉小道17号","cp":" ","direction":"东北","distance":"83","name":"江景园","poiType":"房地产","point":{"x":114.27702814346047,"y":30.545006751698226},"tag":"房地产;住宅区","tel":"","uid":"881a28e7b83af144f942b2d7","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"鹦鹉小道1号","cp":" ","direction":"南","distance":"178","name":"锦绣苑","poiType":"房地产","point":{"x":114.27689339763397,"y":30.546826220962758},"tag":"房地产;住宅区","tel":"","uid":"86828754251cc6a18bdb739b","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区鹦鹉小道29","cp":" ","direction":"北","distance":"192","name":"东星公寓","poiType":"房地产","point":{"x":114.27685746541357,"y":30.54413588242787},"tag":"房地产;住宅区","tel":"","uid":"4630efce6af8a07b5bf6be6a","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区腰路堤30号","cp":" ","direction":"南","distance":"236","name":"睿智幼儿园","poiType":"教育培训","point":{"x":114.27706407568087,"y":30.54733162297987},"tag":"教育培训;幼儿园","tel":"","uid":"3c23b5470bb36606a7c756f6","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区武汉世茂希尔顿酒店5号商寓楼41层","cp":" ","direction":"西","distance":"245","name":"爱弥儿舞蹈艺术","poiType":"教育培训","point":{"x":114.2796242463843,"y":30.545107834227534},"tag":"教育培训;幼儿园","tel":"","uid":"ce2c20de6d424e8cf922138a","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区腰路堤43号","cp":" ","direction":"南","distance":"246","name":"杨泗社区","poiType":"房地产","point":{"x":114.27701916040538,"y":30.547401601511259},"tag":"房地产;住宅区","tel":"","uid":"8e2a741ae09352728bb988d4","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"自力新村42附1","cp":" ","direction":"东","distance":"305","name":"鹦鹉街社区卫生中心","poiType":"医疗","point":{"x":114.27473746441003,"y":30.545426632277523},"tag":"医疗;诊所","tel":"","uid":"00a528f9fa63fb98f822130b","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区阳新路","cp":" ","direction":"西北","distance":"322","name":"世茂锦绣长江52","poiType":"购物","point":{"x":114.2799476363679,"y":30.544221414580585},"tag":"购物;购物中心","tel":"","uid":"abb960cc825fa4944d776ec7","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区鹦鹉洲长江大桥下","cp":" ","direction":"西北","distance":"671","name":"鹦鹉洲汉阳桥梁主题公园","poiType":"旅游景点","point":{"x":114.2797949244312,"y":30.540706757987107},"tag":"旅游景点;公园","tel":"","uid":"5111b3c127ec596788db730d","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}}],"roads":[],"poiRegions":[{"direction_desc":"内","name":"世茂锦绣长江2期","tag":"房地产;住宅区","uid":"4fb8a45a2c5615d4b75f1eef","distance":"0"}],"sematic_description":"世茂锦绣长江2期内","cityCode":218}}
                JSONObject jsonObject = JSON.parseObject(replaced);
                // {"location":{"lng":114.2774764813043,"lat":30.54552971153468},"formatted_address":"湖北省武汉市汉阳区鹦鹉小道","business":"鹦鹉/鹦鹉大道,江汉大学,腰路堤","addressComponent":{"country":"中国","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","province":"湖北省","city":"武汉市","city_level":2,"district":"汉阳区","town":"","adcode":"420105","street":"鹦鹉小道","street_number":"","direction":"","distance":""},"pois":[{"addr":"武汉汉阳区鹦鹉街办事处世茂锦绣长江二期","cp":"","direction":"内","distance":"0","name":"世茂锦绣长江2期","poiType":"房地产","point":{"x":114.27836661867033,"y":30.545426632277523},"tag":"房地产;住宅区","tel":"","uid":"4fb8a45a2c5615d4b75f1eef","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"鹦鹉小道17号","cp":" ","direction":"东北","distance":"83","name":"江景园","poiType":"房地产","point":{"x":114.27702814346047,"y":30.545006751698226},"tag":"房地产;住宅区","tel":"","uid":"881a28e7b83af144f942b2d7","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"鹦鹉小道1号","cp":" ","direction":"南","distance":"178","name":"锦绣苑","poiType":"房地产","point":{"x":114.27689339763397,"y":30.546826220962758},"tag":"房地产;住宅区","tel":"","uid":"86828754251cc6a18bdb739b","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区鹦鹉小道29","cp":" ","direction":"北","distance":"192","name":"东星公寓","poiType":"房地产","point":{"x":114.27685746541357,"y":30.54413588242787},"tag":"房地产;住宅区","tel":"","uid":"4630efce6af8a07b5bf6be6a","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区腰路堤30号","cp":" ","direction":"南","distance":"236","name":"睿智幼儿园","poiType":"教育培训","point":{"x":114.27706407568087,"y":30.54733162297987},"tag":"教育培训;幼儿园","tel":"","uid":"3c23b5470bb36606a7c756f6","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区武汉世茂希尔顿酒店5号商寓楼41层","cp":" ","direction":"西","distance":"245","name":"爱弥儿舞蹈艺术","poiType":"教育培训","point":{"x":114.2796242463843,"y":30.545107834227534},"tag":"教育培训;幼儿园","tel":"","uid":"ce2c20de6d424e8cf922138a","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"武汉市汉阳区腰路堤43号","cp":" ","direction":"南","distance":"246","name":"杨泗社区","poiType":"房地产","point":{"x":114.27701916040538,"y":30.547401601511259},"tag":"房地产;住宅区","tel":"","uid":"8e2a741ae09352728bb988d4","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"自力新村42附1","cp":" ","direction":"东","distance":"305","name":"鹦鹉街社区卫生中心","poiType":"医疗","point":{"x":114.27473746441003,"y":30.545426632277523},"tag":"医疗;诊所","tel":"","uid":"00a528f9fa63fb98f822130b","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区阳新路","cp":" ","direction":"西北","distance":"322","name":"世茂锦绣长江52","poiType":"购物","point":{"x":114.2799476363679,"y":30.544221414580585},"tag":"购物;购物中心","tel":"","uid":"abb960cc825fa4944d776ec7","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}},{"addr":"湖北省武汉市汉阳区鹦鹉洲长江大桥下","cp":" ","direction":"西北","distance":"671","name":"鹦鹉洲汉阳桥梁主题公园","poiType":"旅游景点","point":{"x":114.2797949244312,"y":30.540706757987107},"tag":"旅游景点;公园","tel":"","uid":"5111b3c127ec596788db730d","zip":"","parent_poi":{"name":"","tag":"","addr":"","point":{"x":0.0,"y":0.0},"direction":"","distance":"","uid":""}}],"roads":[],"poiRegions":[{"direction_desc":"内","name":"世茂锦绣长江2期","tag":"房地产;住宅区","uid":"4fb8a45a2c5615d4b75f1eef","distance":"0"}],"sematic_description":"世茂锦绣长江2期内","cityCode":218}
                JSONObject resultObject = jsonObject.getJSONObject("result");
                //"business": "鹦鹉/鹦鹉大道,江汉大学,腰路堤"
                business = resultObject.getString("business");
                //若business中取不到商圈信息，则从pois.tag中取商圈信息
                if (StringUtils.isEmpty(business)) {
                    //    "pois": [
                    //        {
                    //            "addr": "武汉汉阳区鹦鹉街办事处世茂锦绣长江二期",
                    //            "cp": "",
                    //            "direction": "内",
                    //            "distance": "0",
                    //            "name": "世茂锦绣长江2期",
                    //            "poiType": "房地产",
                    //            "point": {
                    //                "x": 114.27836661867033,
                    //                "y": 30.545426632277523
                    //            },
                    //            "tag": "房地产;住宅区",
                    //            "tel": "",
                    //            "uid": "4fb8a45a2c5615d4b75f1eef",
                    //            "zip": "",
                    //            "parent_poi": {
                    //                "name": "",
                    //                "tag": "",
                    //                "addr": "",
                    //                "point": {
                    //                    "x": 0,
                    //                    "y": 0
                    //                },
                    //                "direction": "",
                    //                "distance": "",
                    //                "uid": ""
                    //            }
                    //        }
                    //    ]
                    JSONArray jsonArray = jsonObject.getJSONArray("pois");
                    if (null != jsonArray && jsonArray.size() > 0) {
                        business = jsonArray.getJSONObject(0).getString("tag");
                    }
                }

            }
        }
        System.out.println("business = " + business);
        return business;
    }

    // 对Map内所有value作utf8编码，拼接返回结果
    public static String toQueryString(Map<?, ?> data) throws UnsupportedEncodingException {
        StringBuffer queryString = new StringBuffer();
        for (Entry<?, ?> pair : data.entrySet()) {
            queryString.append(pair.getKey() + "=");
            //URLEncoder.encode作用：将“，”等关键字转义
            queryString.append(URLEncoder.encode((String) pair.getValue(),
                    "UTF-8") + "&");
        }
        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }
        return queryString.toString();
    }

    // 来自stackoverflow的MD5计算方法，调用了MessageDigest库函数，并把byte数组结果转换成16进制
    public static String MD5(String md5) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest
                    .getInstance("MD5");
            byte[] array = md.digest(md5.getBytes());
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < array.length; ++i) {
                sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100)
                        .substring(1, 3));
            }
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
        }
        return null;
    }

}
